package com.um.springboot.starter.utils.condition;


import com.um.springboot.starter.config.SystemSQL;
import com.um.springboot.starter.utils.StringUtil;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @Title sql条件构建器
 * @Description
 * @Author renjunwei
 * @Date 2022/5/5 17:38
 */
public class ConditionBuilder {

    protected Map<String, Object> condition;

    //拼接在getSql()后的自定义sql
    protected String appendSql;

    //sql中被替换部分
    public static final String replaceName = "[condition]";

    /**
     * 创建条件构建器
     * @return
     */
    public ConditionBuilder(Map condition) {
        this.condition = condition;
    }

    /**
     * 创建条件构建器
     * @return
     */
    public static ConditionBuilder create(){
        return new ConditionBuilder(new LinkedHashMap());
    }

    /**
     * 创建条件构建器
     * @return
     */
    public static ConditionBuilder create(Map condition){
        return new ConditionBuilder(condition);
    }

    /**
     * 添加条件，忽略空的条件
     * @param key
     * @param value
     * @return
     */
    public ConditionBuilder put(String key, Object value){
        return this.put(key, value, false);
    }

    /**
     * 添加条件
     * @param key
     * @param value
     * @param allowEmpty
     * @return
     */
    public ConditionBuilder put(String key, Object value, boolean allowEmpty){
        if(allowEmpty || !StringUtil.isEmpty(value)){
            this.condition.put(key, value);
        }
        return this;
    }

    /**
     * 添加条件，忽略空的条件
     * @param key
     * @param value
     * @return
     */
    public ConditionBuilder putLeftLike(String key, Object value){
        return this.putLeftLike(key, value, false);
    }

    /**
     * 添加条件
     * @param key
     * @param value
     * @param allowEmpty
     * @return
     */
    public ConditionBuilder putLeftLike(String key, Object value, boolean allowEmpty){
        if(allowEmpty || !StringUtil.isEmpty(value)){
            this.condition.put(key, "%" + value);
        }
        return this;
    }

    /**
     * 添加条件，忽略空的条件
     * @param key
     * @param value
     * @return
     */
    public ConditionBuilder putRightLike(String key, Object value){
        return this.putRightLike(key, value, false);
    }

    /**
     * 添加条件
     * @param key
     * @param value
     * @param allowEmpty
     * @return
     */
    public ConditionBuilder putRightLike(String key, Object value, boolean allowEmpty){
        if(allowEmpty || !StringUtil.isEmpty(value)){
            this.condition.put(key, value + "%");
        }
        return this;
    }

    /**
     * 添加条件，忽略空的条件
     * @param key
     * @param value
     * @return
     */
    public ConditionBuilder putLike(String key, Object value){
        return this.putLike(key, value, false);
    }

    /**
     * 添加条件
     * @param key
     * @param value
     * @param allowEmpty
     * @return
     */
    public ConditionBuilder putLike(String key, Object value, boolean allowEmpty){
        if(allowEmpty || !StringUtil.isEmpty(value)){
            this.condition.put(key, "%" + value + "%");
        }
        return this;
    }

    /**
     * 添加范围条件
     * @param key
     * @param range
     * @return
     */
    public ConditionBuilder putRange(String key, Range range){
        this.condition.put(key, range);
        return this;
    }

    /**
     * 添加或条件
     * @param orConditions
     * @return
     */
    public ConditionBuilder putOr(Map<String, Object> orConditions){
        this.condition.put(null, orConditions);
        return this;
    }

    /**
     * 创建后的条件构建器
     * @return
     */
    public Map build(){
        return condition;
    }

    /**
     * 创建后的条件构建器转sql
     *
     * @return
     */
    public String getSql(){
        StringBuffer sb = new StringBuffer();

        for(Map.Entry<String, Object> entry : condition.entrySet()){

            //范围查询
            if(entry.getValue() instanceof Range){
                Range range = (Range) entry.getValue();
                if(!StringUtil.isEmpty(range.getBegin())){
                    sb.append(" and ");
                    sb.append(entry.getKey());
                    sb.append(" >= ? ");
                }
                if(!StringUtil.isEmpty(range.getEnd())){
                    sb.append(" and ");
                    sb.append(entry.getKey());
                    sb.append(" <= ? ");
                }
            }

            //或查询
            else if(entry.getValue() instanceof Map){
                Map<String, Object> orConditions = (Map<String, Object>) entry.getValue();
                if(!orConditions.isEmpty()){
                    sb.append(" and ( 1 != 1");
                    orConditions.forEach((key, value) -> sb.append(" or ").append(key).append(" = ?"));
                    sb.append(" )");
                }
            }

            //普通查询
            else{
                sb.append(" and ");
                sb.append(entry.getKey());
                if(StringUtil.getTrim(condition.get(entry.getKey())).contains("%")) {
                    sb.append(" like ? ");
                }else{
                    sb.append(" = ? ");
                }
            }
        }

        if(null != appendSql){
            return sb.append(appendSql).toString();
        }
        return sb.toString();
    }

    /**
     * 创建后的条件构建器转sql的值
     *
     * @return
     */
    public List getParams(){
        List list = new ArrayList();

        for(Map.Entry<String, Object> entry : condition.entrySet()){

            //范围查询
            if(entry.getValue() instanceof Range){
                Range range = (Range) entry.getValue();
                if(!StringUtil.isEmpty(range.getBegin())){
                    list.add(range.getBegin());
                }
                if(!StringUtil.isEmpty(range.getEnd())){
                    list.add(range.getEnd());
                }
            }

            //或查询
            else if(entry.getValue() instanceof Map){
                Map<String, Object> orConditions = (Map<String, Object>) entry.getValue();
                if(!orConditions.isEmpty()){
                    orConditions.forEach((key, value) -> list.add(value));
                }
            }

            //普通查询
            else{
                list.add(entry.getValue());
            }

        }
        return list;
    }

    /**
     * 设置拼接在getSql()后的自定义sql
     * @param appendSql
     */
    public void setAppendSql(String appendSql) {
        this.appendSql = appendSql;
    }

    /**
     * 通过sqlName获取完整sql
     * @param sqlName
     * @return
     */
    public String getFullSql(String sqlName){
        return getFullSql(sqlName, replaceName);
    }

    /**
     * 通过sqlName获取完整sql
     * @param sqlName
     * @param replaceName
     * @return
     */
    public String getFullSql(String sqlName, String replaceName){
        return SystemSQL.getInstance().getSystemSQL(sqlName).replace(replaceName, getSql());
    }
}
